//
//  VideoCallViewController.swift
//  Liao
//
//  Created by 范东 on 2022/3/17.
//

import UIKit
import FDUIKit
import AgoraRtcKit
import AVFAudio

enum CallType: Int {
    case voiceCall = 1
    case videoCall = 2
}

class VideoCallViewController: BaseViewController {
    
    var type = CallType.voiceCall
    
    let margin: CGFloat = 15
    
    var agoraKit: AgoraRtcEngineKit?
    var channelId = ""
    
    var audioPlayer: AVAudioPlayer?
    
    /// 是否是发起者
    var isInitiator = false
    var fromUser = V2TIMGroupMemberFullInfo()
    
    
    /// 通话时长
    var timer: Timer?
    var timeCount: Int = 0
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        view.addSubview(bgImageView)
        view.addSubview(visualView)
        view.addSubview(shadowView)
        view.addSubview(iconImageView)
        view.addSubview(nameLabel)
        view.addSubview(statusLabel)
        
        bgImageView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        visualView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        shadowView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        
        if type == .videoCall {
            view.addSubview(remoteView)
            view.addSubview(localView)
            view.addSubview(switchCameraBtn)
            iconImageView.snp.makeConstraints { make in
                make.right.equalToSuperview().offset(-20)
                make.size.equalTo(CGSize(width: 100, height: 100))
                make.top.equalToSuperview().offset(CGFloat.topHeight)
            }
            nameLabel.snp.makeConstraints { make in
                make.right.equalTo(self.iconImageView.snp.left).offset(-20)
                make.top.equalTo(self.iconImageView).offset(20)
            }
            statusLabel.snp.makeConstraints { make in
                make.right.equalTo(self.nameLabel)
                make.top.equalTo(self.nameLabel.snp.bottom).offset(10)
            }
            switchCameraBtn.snp.makeConstraints { make in
                make.top.equalToSuperview().offset(CGFloat.topHeight)
                make.left.equalToSuperview().offset(20)
                make.size.equalTo(CGSize(width: 44, height: 44))
            }
        }else{
            iconImageView.snp.makeConstraints { make in
                make.top.equalToSuperview().offset(CGFloat.topHeight)
                make.size.equalTo(CGSize(width: 100, height: 100))
                make.centerX.equalToSuperview()
            }
            nameLabel.snp.makeConstraints { make in
                make.centerX.equalToSuperview()
                make.top.equalTo(self.iconImageView.snp.bottom).offset(20)
            }
            statusLabel.snp.makeConstraints { make in
                make.centerX.equalToSuperview()
                make.top.equalTo(self.nameLabel.snp.bottom).offset(10)
            }
        }
        
        
        
        bgImageView.sd_setImage(with: URL(string: fromUser.faceURL))
        iconImageView.sd_setImage(with: URL(string: fromUser.faceURL))
        nameLabel.text = fromUser.nickName
        
        view.addSubview(micBtn)
        view.addSubview(endBtn)
        view.addSubview(speakerBtn)
        view.addSubview(timeLabel)
        endBtn.snp.makeConstraints { make in
            make.size.equalTo(CGSize(width: 64, height: 90))
            make.bottom.equalToSuperview().offset(-CGFloat.safeAreaBottomHeight - self.margin)
            make.centerX.equalToSuperview()
        }
        micBtn.snp.makeConstraints { make in
            make.size.equalTo(CGSize(width: 44, height: 70))
            make.centerY.equalTo(self.endBtn)
            make.right.equalTo(self.endBtn.snp.left).offset(-40)
        }
        speakerBtn.snp.makeConstraints { make in
            make.size.equalTo(CGSize(width: 44, height: 70))
            make.centerY.equalTo(self.endBtn)
            make.left.equalTo(self.endBtn.snp.right).offset(40)
        }
        timeLabel.snp.makeConstraints { make in
            make.bottom.equalTo(self.endBtn.snp.top).offset(-30)
            make.centerX.equalToSuperview()
        }
        if isInitiator {
            setupCallAudio()
        }else{
            statusLabel.text = "连接中..."
        }
        
        setupAgoraKit()
        if type == .videoCall {
            setupLocalView()
        }
        joinChannel()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        UIApplication.shared.isIdleTimerDisabled = false
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        leaveChannel()
        UIApplication.shared.isIdleTimerDisabled = true
    }
    
    func setupCallAudio(){
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: Bundle.main.path(forResource: "calling", ofType: "mp3")!))
            audioPlayer?.numberOfLoops = -1
            audioPlayer?.play()
        } catch let error {
            debugPrint(error.localizedDescription)
        }
    }
    
    func setupAgoraKit(){
        let config = AgoraRtcEngineConfig()
        config.appId = "b9a5b1f834454f838148d5f983db2cb8"
        let logConfig = AgoraLogConfig()
        logConfig.level = .info
        config.logConfig = logConfig
        agoraKit = AgoraRtcEngineKit.sharedEngine(with: config, delegate: self)
        if type == .videoCall {
            let videoConfig = AgoraVideoEncoderConfiguration()
            videoConfig.dimensions = AgoraVideoDimension1280x720
            agoraKit?.setVideoEncoderConfiguration(videoConfig)
        }
        
    }
    
    func setupLocalView(){
        agoraKit?.enableVideo()
        let canvas = AgoraRtcVideoCanvas()
        canvas.uid = UInt(FMRadio.getUserId())
        canvas.renderMode = .fit
        canvas.view = localView
        agoraKit?.setupLocalVideo(canvas)
        agoraKit?.setLocalRenderMode(.hidden)
    }
    
    func joinChannel(){
        agoraKit?.joinChannel(byToken: "", channelId: channelId, info: "", uid: UInt(FMRadio.getUserId()), joinSuccess: { channel, uid, elapsed in
            debugPrint("\(uid)加入"+channel+"成功")
        })
    }
    
    func leaveChannel(){
        audioPlayer?.stop()
        audioPlayer = nil
        agoraKit?.leaveChannel()
        AgoraRtcEngineKit.destroy()
    }
    
    @objc func micBtnAction(sender: UIButton){
        sender.isSelected = !sender.isSelected
        agoraKit?.muteLocalAudioStream(sender.isSelected)
    }
    
    @objc func endBtnAction(sender: UIButton){
        let messageModel = MessageModel()
        messageModel.type = MessageType.callEnd.rawValue
        messageModel.desc = NSLocalizedString("End a video call", comment: "")
        IMManager.send(toUserId: fromUser.userID, message: messageModel) { result in
            debugPrint("结束了视频通话")
            self.leaveChannel()
            self.timer?.invalidate()
            self.dismiss(animated: true, completion: nil)
        } failure: { error in
            self.view.makeToast(error)
        }
    }
    
    @objc func speakerBtnAction(sender: UIButton){
        sender.isSelected = !sender.isSelected
        agoraKit?.setEnableSpeakerphone(sender.isSelected)
    }
    
    @objc func switchCameraBtnAction(){
        agoraKit?.switchCamera()
    }
    
    @objc func timerAction(){
        timeCount = timeCount + 1
        let min = timeCount / 60
        let sec = timeCount % 60
        timeLabel.text = String.init(format: "%02d:%02d", min,sec)
    }
    
    lazy var bgImageView: UIImageView = {
        let bgImageView = UIImageView(frame: .zero)
        bgImageView.contentMode = .scaleAspectFill
        return bgImageView
    }()
    
    lazy var visualView: UIVisualEffectView = {
        let visualView = UIVisualEffectView(effect: UIBlurEffect.qmui_effect(withBlurRadius: 10))
        return visualView
    }()
    
    lazy var shadowView: UIView = {
        let shadowView = UIView(frame: .zero)
        shadowView.backgroundColor = .black.withAlphaComponent(0.5)
        return shadowView
    }()
    
    lazy var localView: UIView = {
        let localView = UIView(frame: CGRect(x: 0, y: 0, width: .screenW, height: .screenH))
        return localView
    }()
    
    lazy var remoteView: UIView = {
        let remoteView = UIView(frame: CGRect(x: 0, y: 0, width: .screenW, height: .screenH))
        return remoteView
    }()
    
    lazy var nameLabel: UILabel = {
        let timeLabel = UILabel(frame: .zero)
        timeLabel.textColor = .systemBackground
        timeLabel.font = .systemFont(ofSize: 20, weight: .medium)
        return timeLabel
    }()
    
    lazy var iconImageView: UIImageView = {
        let bgImageView = UIImageView(frame: .zero)
        bgImageView.contentMode = .scaleAspectFill
        bgImageView.clipsToBounds = true
        bgImageView.layer.cornerRadius = 10
        return bgImageView
    }()
    
    lazy var statusLabel: UILabel = {
        let timeLabel = UILabel(frame: .zero)
        timeLabel.textColor = .systemGray3
        timeLabel.font = .systemFont(ofSize: 15)
        timeLabel.text = NSLocalizedString("WaitAccept", comment: "")
        return timeLabel
    }()
    
    lazy var timeLabel: UILabel = {
        let timeLabel = UILabel(frame: .zero)
        timeLabel.textColor = .systemGray
        timeLabel.font = .systemFont(ofSize: 15)
        timeLabel.isHidden = true
        return timeLabel
    }()
    
    lazy var micBtn: QMUIButton = {
        let micBtn = QMUIButton(type: .custom)
        micBtn.setImage(UIImage(named: "icon_mute"), for: .normal)
        micBtn.setImage(UIImage(named: "icon_mute_on"), for: .selected)
        micBtn.setTitle(NSLocalizedString("Mic", comment: ""), for: .normal)
        micBtn.imagePosition = .top
        micBtn.titleLabel?.font = .systemFont(ofSize: 14)
        micBtn.spacingBetweenImageAndTitle = 10
        micBtn.setTitleColor(.systemGray, for: .normal)
        micBtn.addTarget(self, action: #selector(micBtnAction(sender:)), for: .touchUpInside)
        return micBtn
    }()
    
    lazy var endBtn: QMUIButton = {
        let endBtn = QMUIButton(type: .custom)
        endBtn.setImage(UIImage(named: "icon_hangup"), for: .normal)
        endBtn.setTitle(NSLocalizedString("Hangup", comment: ""), for: .normal)
        endBtn.imagePosition = .top
        endBtn.spacingBetweenImageAndTitle = 10
        endBtn.setTitleColor(.systemGray, for: .normal)
        endBtn.titleLabel?.font = .systemFont(ofSize: 14)
        endBtn.addTarget(self, action: #selector(endBtnAction(sender:)), for: .touchUpInside)
        return endBtn
    }()
    
    lazy var speakerBtn: QMUIButton = {
        let speakerBtn = QMUIButton(type: .custom)
        speakerBtn.setImage(UIImage(named: "icon_handsfree"), for: .normal)
        speakerBtn.setImage(UIImage(named: "icon_handsfree_on"), for: .selected)
        speakerBtn.setTitle(NSLocalizedString("Speaker", comment: ""), for: .normal)
        speakerBtn.imagePosition = .top
        speakerBtn.spacingBetweenImageAndTitle = 10
        speakerBtn.setTitleColor(.systemGray, for: .normal)
        speakerBtn.titleLabel?.font = .systemFont(ofSize: 14)
        speakerBtn.addTarget(self, action: #selector(speakerBtnAction(sender:)), for: .touchUpInside)
        return speakerBtn
    }()
    
    lazy var switchCameraBtn: UIButton = {
        let switchCameraBtn = UIButton(type: .custom)
        switchCameraBtn.setImage(UIImage(named: "icon_switch_camera"), for: .normal)
        switchCameraBtn.addTarget(self, action: #selector(switchCameraBtnAction), for: .touchUpInside)
        return switchCameraBtn
    }()
    
    override var preferredStatusBarStyle: UIStatusBarStyle{
        .lightContent
    }
}

extension VideoCallViewController: AgoraRtcEngineDelegate{
    func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) {
        audioPlayer?.stop()
        if type == .videoCall {
            //视频通话
            let width: CGFloat = .screenW / 3
            let height: CGFloat = width * 16 / 9
            UIView.animate(withDuration: 0.25) {
                self.localView.frame = CGRect(x: self.margin, y: .screenH - height - .safeAreaBottomHeight - self.margin * 2 - 70, width: width, height: height)
            } completion: { finished in
                let videoCanvas = AgoraRtcVideoCanvas()
                videoCanvas.uid = uid
                videoCanvas.renderMode = .fit
                videoCanvas.view = self.remoteView
                // 设置远端视图
                self.agoraKit?.setupRemoteVideo(videoCanvas)
                self.agoraKit?.setRemoteRenderMode(uid, mode: .hidden)
            }
            statusLabel.text = ""
            nameLabel.text = ""
            iconImageView.image = nil
        }else{
            //语音通话
            statusLabel.text = ""
        }
        timeLabel.isHidden = false
        timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
    }
    
    func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason) {
        leaveChannel()
    }
    
}
